/**
 * Copyright (C) 2017 - 2020 https://github.com/joewee
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.bifrost.service;

import com.bifrost.constant.SendCouponType;
import com.bifrost.entity.*;
import com.bifrost.exception.BonusPointsNotEnoughException;
import com.bifrost.exception.CancleConsumeException;
import com.bifrost.exception.ConsumeCouponException;
import com.bifrost.model.CouponResponse;
import com.bifrost.wrapper.CouponWrapper;

import java.util.List;
import java.util.Set;

/**
 *
 *
 *@author joewee
 *@version 1.0.0
 *@Date 2017/11/7 19:38
 */
public interface CouponService {

    /**
     * 获取会员已使用的优惠券
     * @param customer 会员
     * @return
     */
    List<CouponDetail> getUsedCoupons(Customer customer);

    /**
     * 获取会员所有未使用的优惠券
     * @param customer 会员
     * @return
     */
    List<CouponDetail> getUnusedCoupons(Customer customer);

    /**
     * 获取会员已过期的优惠券
     * @param customer 会员
     * @return
     */
    List<CouponDetail> getExpiredCoupons(Customer customer);

    /**
     * 查询所有优惠券
     * @param order
     * @return
     */
    List<CouponWrapper> getCoupons(Order order);

    /**
     * 结合订单验证优惠券是否可用
     * @param order
     * @param list
     * @return
     */
    List<CouponWrapper> validate(Order order, List<CouponDetail> list);

    /**
     * 验证订单是否适用该优惠券
     * @param order
     * @param detail
     * @return
     */
    CouponWrapper validate(Order order, CouponDetail detail) ;
    /**
     * 验证优惠券是否过期，返回未过期优惠券
     * @param detail
     * @return
     */
    boolean isExpiration(CouponDetail detail);

    /**
     * 查找默认优惠券
     * @param wrappers
     * @return
     */
    List<CouponWrapper> sortByValue(List<CouponWrapper> wrappers) ;

    /**
     * 根据优惠券码获取优惠券
     * @param codes
     * @return
     */
    List<CouponDetail> getCustomerCouponByCode(Customer customer,Set<Long> codes);

    /**
     * 查询会员已使用指定优惠券的最大数量
     * @param customer
     * @param coupon
     * @return
     */
    int getCustomerMaxUsed(Customer customer,Coupon coupon);

    //Coupon addTimesUsed(Coupon coupon,Integer times);

    /**
     * 领取指定id的优惠券
     * @param customer
     * @param id
     * @param lottery
     * @return
     */
    CouponResponse getCoupon(Customer customer, Long id, SendCouponType lottery) throws BonusPointsNotEnoughException;


    /**
     * 获取指定类型的优惠券
     * @param type
     * @param store
     * @return
     */
    List<Coupon> getCoupons(String type,MerchantStore store);

    int countCoupons(Customer customer);

    /**
     * 使用优惠券
     * @param detail
     */
    void setCouponDetailIsUsed(CouponDetail detail);

    /**
     * 回滚优惠券
     * @param detail
     */
    void rollbackCouponDetailIsUnused(CouponDetail detail);

    /**
     * 兑换优惠券
     * @param customer
     * @param code
     * @return
     */
    List<CouponResponse> redeemCoupon(Customer customer,String code);

    /**
     *根据核销码查询优惠券
     *  @param code
     * @return
     */
    CouponDetail findByConsumeCode(String code,MerchantStore store);

    /**
     * 查询用户指定的优惠券
     * @param id
     * @return
     */
    CouponDetail findCouponDetail(Customer customer,Long id);

    /**
     * 生成消费码
     * @param detail
     */
    void generateConsumeCode(CouponDetail detail) throws ConsumeCouponException;

    boolean isAvailable(CouponDetail detail);

    /**
     *核销码是否过期
     *  @param detail
     * @return
     */
    boolean isConsumeCodeExpired(CouponDetail detail);
    /**
     * 优惠券是否在有效期
     * @param detail
     * @return
     */
    boolean isActive(CouponDetail detail);

    /**
     * 线下核销优惠券
     * @param outTradeNo
     * @param consumeCode
     * @param totalFee
     * @return
     * @throws ConsumeCouponException
     */
    Long  consumeCoupon(String outTradeNo, String consumeCode, int totalFee) throws ConsumeCouponException;


    /**
     * 取消线下优惠券的核销（冲正）
     * @param outTradeNo
     * @throws CancleConsumeException
     */
    void cancleConsumeCoupon(String outTradeNo) throws CancleConsumeException;


    /**
     * 退还优惠券
     * @param outTradeNo
     * @param transactionId
     * @throws CancleConsumeException
     */
    Long refundCoupon(String outTradeNo, Long transactionId) throws CancleConsumeException;

    /**
     * 退券查询
     * @param outTradeNo
     * @param transactionId
     */
    boolean refundQuery(String outTradeNo, Long transactionId) throws CancleConsumeException;

    CouponDetail findByConsumeCode(String code);

    /**
     * 主动发发优惠券
     */
    void autoGrantCoupon();

    CouponDetail queryByConsumeCode(String code);

    void reissue(Long gameId);

    void addAutoCouponList(String phones, String couponIds, String storeCode);

    Coupon findCoupon(Long couponId);

    boolean isBetweenReleasePeriod(Coupon coupon);
}

